﻿namespace MicroCloud.Services
{
    /// <summary>
    /// EmailReceiver托管服务
    /// </summary>
    public class EmailReceiverHostedService : IHostedService, IDisposable
    {
        /// <summary>
        /// 初始化一个 EmailReceiver 托管服务的新实例
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public EmailReceiverHostedService(IServiceProvider provider)
        {
            ServiceProvider = provider;

            EmailReceiveTimer = new Timer(ExecuteEmailReceive, null, Timeout.Infinite, 0);
        }

        #region 属性
        /// <summary>
        /// 获取 服务提供者对象
        /// </summary>
        protected IServiceProvider ServiceProvider { get; }
        
        /// <summary>
        /// 获取 日志对象
        /// </summary>
        protected ILogger Logger => ServiceProvider.GetLogger(GetType());
        
        /// <summary>
        /// 获取 邮件配置信息
        /// </summary>
        protected EmailOption Options => ServiceProvider.GetMicroCloudOptions().Email;
        
        /// <summary>
        /// 获取 邮件接收功能
        /// </summary>
        protected IEmailReceiver EmailReceiver => ServiceProvider.GetService<IEmailReceiver>();

        /// <summary>
        /// 获取 事件总线
        /// </summary>
        protected IEventBus EventBus => ServiceProvider.GetService<IEventBus>();

        /// <summary>
        /// 获取 邮件接收定时器
        /// </summary>
        protected Timer EmailReceiveTimer { get; }

        #endregion

        #region 方法
        /// <summary>
        /// 异步启动
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task StartAsync(CancellationToken cancellationToken)
        {
            Logger.LogInformation("启动邮件接收器 EmailReceiver 托管服务");

            SetEmailReceiveTask();

            return Task.CompletedTask;
        }

        /// <summary>
        /// 异步停止
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task StopAsync(CancellationToken cancellationToken)
        {
            Logger.LogInformation("停止邮件接收器 EmailReceiver 托管服务");

            EmailReceiveTimer?.Change(Timeout.Infinite, 0);

            return Task.CompletedTask;
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        /// <summary>
        /// 释放资源
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                EmailReceiveTimer?.Dispose();
            }
        }

        #endregion

        #region 受保护的方法
        /// <summary>
        /// 设置邮件接收任务
        /// </summary>
        protected void SetEmailReceiveTask()
        {
            var receiveInterval = Options.ReceiveInterval;
            if (receiveInterval <= 0)
            {
                receiveInterval = 1; //1分钟间隔
            }
            DateTime now = DateTime.Now;
            DateTime delayClock = now.AddMinutes(receiveInterval); //延迟时间
            if (now > delayClock)
            {
                delayClock = delayClock.AddMinutes(receiveInterval);
            }
            int msUntilFour = (int)((delayClock - now).TotalMilliseconds);

            EmailReceiveTimer.Change(msUntilFour, Timeout.Infinite);
            //EmailReceiveTimer.Change(5000, Timeout.Infinite);
        }

        /// <summary>
        /// 执行邮件接收任务
        /// </summary>
        /// <param name="state"></param>
        protected void ExecuteEmailReceive(object state = null)
        {
            try
            {
                var receiveInterval = Options.ReceiveInterval;
                if (receiveInterval > 0)
                {
                    var receiverOptions = Options.Receiver;
                    var messages = EmailReceiver.ReceiveEmail(receiverOptions);
                    if (messages?.Count > 0)
                    {
                        EmailReceiveEventData eventData = new()
                        {
                            IsSystem = true,
                            ReceiverOptions = receiverOptions,
                            Messages = messages
                        };
                        //触发事件
                        EventBus?.Publish(eventData);
                    }
                }
            }
            catch (System.Exception ex)
            {
                Logger.LogError(ex, "{message}", ex.Message);
            }
            finally
            {
                //再次设定
                SetEmailReceiveTask();
            }
        }

        #endregion

    }

}
